package com.sl.diary.activity;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.sl.diary.R;
import com.sl.diary.component.DatePickerDialog;
import com.sl.diary.db.DBManager;
import com.sl.diary.model.ImageModel;
import com.sl.diary.model.PointModel;
import com.sl.diary.model.TourModel;
import com.sl.diary.model.TravelModel;
import com.sl.diary.util.Constant;
import com.sl.diary.util.DLog;
import com.sl.diary.util.Util;

// TODO: Auto-generated Javadoc
/**
 * The Class A002_MainMapScreen.
 */
public class A002_MainMapScreen extends FragmentActivity implements
							OnClickListener, OnItemClickListener, 
							OnMapClickListener, OnMarkerClickListener,
							OnCameraChangeListener{
	
	/** The tag. */
	private static String TAG = "A002_MainMapScreen";
	
	/** The btn_show_photo. */
	private ImageButton btn_back, btn_add_travel,
						btn_show_type, btn_show_photo;
	
	// layout for dialog
	/** The txt_description. */
	private EditText 	txt_radius, txt_description;
	
	/** The txt_error. */
	private TextView 	txt_from, txt_to, txt_error;
	
	/** The date_picker_to. */
	private ImageButton date_picker_from, date_picker_to;
	
	/** The chk_auto. */
	private CheckBox 	chk_auto;
	
	/** The btn_cancel. */
	private Button 		btn_save, btn_cancel;
	
	private RelativeLayout layout_header;
	
	/** The dialog add point. */
	private Dialog 		dialogAddPoint;
	
	/** The show map type array. */
	private String[] showMapTypeArray = { "Normal", "Satellite", 
										"Satellite and Street",
										"Terrain"};
	
	/** The show photo array. */
	private String[] showPhotoArray = { "Show points with photo",
										"Show points without photo",
										"Empty map" };
	
	/** The map type. */
	private int[] mapType = {GoogleMap.MAP_TYPE_NORMAL, GoogleMap.MAP_TYPE_SATELLITE,
							GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_TERRAIN};
	
	/** The point list. */
	private ArrayList<PointModel> pointList;
	
	/** The date from. */
	private int DATE_FROM 	= 1;
	
	/** The date to. */
	private int DATE_TO 	= 2;
	
	/** The date_from. */
	private Date date_from;
	
	/** The date_to. */
	private Date date_to;
	
	/** The m google map. */
	private GoogleMap mGoogleMap;
	
	/** The tapped lat long. */
	private LatLng tappedLatLong;
	
	/** The tapped marker. */
	private Marker tappedMarker;
	
	/** The Constant MAP_ZOOM_SIZE. */
	private static final int MAP_ZOOM_SIZE = 16;
//	private LocationManager locationManager;
	/** The db. */
	private DBManager db;
	
	/** The none. */
	private int NONE 			= 0;
	
	/** The show map type. */
	private int SHOW_MAP_TYPE 	= 1;
	
	/** The show photo. */
	private int SHOW_PHOTO 		= 2;
	
	/** The dialog show. */
	private int DIALOG_SHOW 	= NONE;
	
	/** The choose travel. */
	private int CHOOSE_TRAVEL 	= 20;
	
	/* (non-Javadoc)
	 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.a002_main_map_screen);
		
		db = new DBManager(getApplicationContext());
		db.open();
		this.initView();
	}
	
	/**
	 * Inits the view.
	 */
	private void initView() {
		DLog.e(TAG, "initView A002");
		DLog.e(TAG, "memory: " + Util.getMemory(this));
		layout_header = (RelativeLayout) findViewById(R.id.a002_layout_header);
		
		btn_back 		= (ImageButton) findViewById(R.id.btn_back);
		btn_add_travel 	= (ImageButton) findViewById(R.id.btn_add_travel);
		btn_show_type 	= (ImageButton) findViewById(R.id.btn_show_type);
		btn_show_photo 	= (ImageButton) findViewById(R.id.btn_show_photo);
		
		btn_back.setOnClickListener(this);
		btn_add_travel.setOnClickListener(this);
		btn_show_type.setOnClickListener(this);
		btn_show_photo.setOnClickListener(this);
		
		SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager()
				.findFragmentById(R.id.fragment_map);
		mGoogleMap = fragment.getMap();
		mGoogleMap.setOnMapClickListener(this);
		mGoogleMap.setMyLocationEnabled(true);
		mGoogleMap.setOnMarkerClickListener(this);
		
		double latitude = getIntent().getDoubleExtra("latitude", -1);
		double longitude = getIntent().getDoubleExtra("longitude", -1);
			
		pointList = new ArrayList<PointModel>();
		pointList = getIntent().getParcelableArrayListExtra("point_list");
		
		if(latitude != -1 && longitude != -1) {
			CameraUpdate camera = CameraUpdateFactory
					.newCameraPosition(new CameraPosition.Builder()
						.target(new LatLng(latitude, longitude))
						.zoom(MAP_ZOOM_SIZE).build());
			mGoogleMap.animateCamera(camera);
			DLog.e(TAG, "memory start get image: " + Util.getMemory(this));
			for (PointModel point: pointList) {
				// get image
				List<ImageModel> images = db.getAllImageOfPoint(point.getId());
				Marker marker = mGoogleMap.addMarker(new MarkerOptions()
									.position(new LatLng(point.getLatitude(), point.getLongitude()))
									.snippet("" + point.getId()));
				if(images.size() <= 0) {
					marker.setIcon(BitmapDescriptorFactory
							.fromBitmap(BitmapFactory
									.decodeResource(getResources(), R.drawable.icon_camera_marker)));
				} else {
					ImageModel image = images.get(0);
					Bitmap bmp = Util.decodeImageMarker(image.getName(), this);
					if(bmp != null)
						marker.setIcon(BitmapDescriptorFactory.fromBitmap(bmp));
					else
						marker.setIcon(BitmapDescriptorFactory
								.fromBitmap(BitmapFactory
										.decodeResource(getResources(), R.drawable.icon_camera_marker)));
					
				}
				
			}
			DLog.e(TAG, "memory stop get image: " + Util.getMemory(this));
		} else {
			Toast.makeText(this, "Can't get current location", Toast.LENGTH_LONG).show();
		}
		
	}
	
	/**
	 * Inits the view for dialog.
	 */
	private void initViewForDialog(){
		txt_radius 		= (EditText) dialogAddPoint.findViewById(R.id.txt_radius);
		txt_description = (EditText) dialogAddPoint.findViewById(R.id.txt_description);
		txt_from 		= (TextView) dialogAddPoint.findViewById(R.id.txt_from);
		txt_to 			= (TextView) dialogAddPoint.findViewById(R.id.txt_to);
		txt_error		= (TextView) dialogAddPoint.findViewById(R.id.txt_error);
		
		date_picker_from 	= (ImageButton) dialogAddPoint.findViewById(R.id.date_picker_from);
		date_picker_to 		= (ImageButton) dialogAddPoint.findViewById(R.id.date_picker_to);
		chk_auto 			= (CheckBox) dialogAddPoint.findViewById(R.id.chk_auto_register);
		btn_save 			= (Button) dialogAddPoint.findViewById(R.id.btn_save);
		btn_cancel 			= (Button) dialogAddPoint.findViewById(R.id.btn_cancel);
		
		date_picker_from.setOnClickListener(this);
		date_picker_to.setOnClickListener(this);
		btn_save.setOnClickListener(this);
		btn_cancel.setOnClickListener(this);
		
		txt_from.setOnClickListener(this);
		txt_to.setOnClickListener(this);
	}
	
	/* (non-Javadoc)
	 * @see android.support.v4.app.FragmentActivity#onResume()
	 */
	@Override
	protected void onResume() {
	    super.onResume();
	       
	}
	
	/* (non-Javadoc)
	 * @see android.view.View.OnClickListener#onClick(android.view.View)
	 */
	@Override
	public void onClick(View v) {
		Intent i = new Intent();
		switch (v.getId()) {
		case R.id.btn_back:
			i.setClass(this, A003_TravelList.class);
			i.putExtra("type", Constant.TRAVEL_LIST);
			startActivity(i);
			break;
		case R.id.btn_add_travel:
			i.setClass(this, A005_RegisterTravel.class);
			startActivity(i);
			break;
		case R.id.btn_show_type:
			DIALOG_SHOW = SHOW_MAP_TYPE;
			setPopup(showMapTypeArray, v);
			break;
		case R.id.btn_show_photo:
			DIALOG_SHOW = SHOW_PHOTO;
			setPopup(showPhotoArray, v);
			break;
		case R.id.date_picker_from:
			showDatePickerDialog(txt_from, date_picker_from, DATE_FROM);
			break;
		case R.id.date_picker_to:
			showDatePickerDialog(txt_to, date_picker_to, DATE_TO);
			break;
		case R.id.btn_save:
			String error = checkField();
			if(!error.equals(Constant.BANK)) {
				txt_error.setText(error);
				txt_error.setVisibility(View.VISIBLE);
			} else {
				if(chk_auto.isChecked()) {
					SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
					String travel_id = db.addTravel(new TravelModel("", dateFormat.format(new Date()), 
															"", new Date(), new Date(), ""));
					
					String tour_id = db.addTour(new TourModel("", travel_id, dateFormat.format(new Date()), 
										"", 1, new Date(), new Date(), TourModel.POINT, true, 100, 0, 0));
					
					String point_id = db.addPoint(new PointModel("", tappedLatLong.latitude, tappedLatLong.longitude, tour_id));
					
					mGoogleMap.addMarker(new MarkerOptions()
						.position(new LatLng(tappedLatLong.latitude, tappedLatLong.longitude))
						.icon(BitmapDescriptorFactory
								.fromBitmap(BitmapFactory
										.decodeResource(getResources(), R.drawable.icon_camera_marker))));
				} else {
					i = new Intent(this, A003_TravelList.class);
					i.putExtra("type", Constant.CHOOSE_TRAVEL);
					startActivityForResult(i, CHOOSE_TRAVEL);
				}
				dialogAddPoint.dismiss();
			}
			
			break;
		case R.id.btn_cancel:
			dialogAddPoint.dismiss();
			break;
		case R.id.txt_from:
			showDatePickerDialog(txt_from, date_picker_from, DATE_FROM);
			break;
		case R.id.txt_to:
			showDatePickerDialog(txt_to, date_picker_to, DATE_TO);
			break;
		default:
			break;
		}
	}
	
	/* (non-Javadoc)
	 * @see android.support.v4.app.FragmentActivity#onActivityResult(int, int, android.content.Intent)
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent data) {
		if(requestCode == CHOOSE_TRAVEL) {
			
		}
	}
	
	/**
	 * Sets the popup.
	 *
	 * @param data the data
	 * @param view the view
	 */
	private void setPopup(String[] data, View view){
		LayoutInflater layoutInflater 
							= (LayoutInflater)getBaseContext()
							.getSystemService(LAYOUT_INFLATER_SERVICE);  
		View popupView = layoutInflater.inflate(R.layout.layout_popup_shop_map_type, null);  
		final PopupWindow popupWindow = new PopupWindow(
				popupView, 
				LayoutParams.WRAP_CONTENT,  
				LayoutParams.WRAP_CONTENT);
		
		ListView list = (ListView) popupView.findViewById(R.id.list_show);
		list.setAdapter(new ArrayAdapter<String>(this, R.layout.layout_popup_item, R.id.txt_item, data));
		list.setOnItemClickListener(this);
		
		popupWindow.setTouchable(true);
		popupWindow.setFocusable(true);
		popupWindow.setOutsideTouchable(true);
		popupWindow.setBackgroundDrawable(new BitmapDrawable());
		popupWindow.setTouchInterceptor(new View.OnTouchListener() {
	        public boolean onTouch(View v, MotionEvent event) {
	            if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
	            	popupWindow.dismiss();
	            	DIALOG_SHOW = NONE;
	                return true;
	            }
	            return false;
	        }
	    });

		popupWindow.showAsDropDown(view, -50, 0);
	}
	
	

	/* (non-Javadoc)
	 * @see com.google.android.gms.maps.GoogleMap.OnMapClickListener#onMapClick(com.google.android.gms.maps.model.LatLng)
	 */
	@Override
	public void onMapClick(LatLng point) {
		tappedLatLong = point;
		showDialogAddPoint();
	}

	/* (non-Javadoc)
	 * @see android.support.v4.app.FragmentActivity#onPause()
	 */
	@Override
	public void onPause(){
		db.close();
		super.onPause();
	}
	
	/**
	 * Show dialog add point.
	 */
	private void showDialogAddPoint() {
		dialogAddPoint = new Dialog(this, R.style.FullHeightDialog);
		dialogAddPoint.setContentView(R.layout.popup_add_point);
		dialogAddPoint.setCanceledOnTouchOutside(false);
		
		initViewForDialog();
		
		dialogAddPoint.show();
	}
	
	/**
	 * show date picker dialog.
	 *
	 * @param viewId the id of departure/end date image button
	 * @param dateButton the date button
	 * @param dateType the date type
	 */
	private final void showDatePickerDialog(final TextView viewId, 
										final View dateButton, final int dateType) {
		final Calendar calendar = Calendar.getInstance();
		DatePickerDialog datePickerDialog = new DatePickerDialog(
				A002_MainMapScreen.this, R.style.DialogSlideAnim, calendar,
				null, new DatePickerDialog.DatePickerListner() {

					@Override
					public void OnDoneButton(Dialog dialog, Calendar c) {

						calendar.set(Calendar.YEAR, c.get(Calendar.YEAR));
						calendar.set(Calendar.MONTH, c.get(Calendar.MONTH));
						calendar.set(Calendar.DAY_OF_MONTH,
								c.get(Calendar.DAY_OF_MONTH));

						Date selectedDate = new Date(
								calendar.get(Calendar.YEAR) - 1900,
								calendar.get(Calendar.MONTH),
								calendar.get(Calendar.DAY_OF_MONTH));
						
						if(dateType == DATE_FROM)
							date_from = selectedDate;
						else
							date_to = selectedDate;
							
						viewId.setText(Util.convertDateToString(selectedDate));
						viewId.setVisibility(View.VISIBLE);
						dateButton.setVisibility(View.GONE);
						dialog.dismiss();
					}

					@Override
					public void OnCancelButton(Dialog dialog) {
						dialog.dismiss();
					}
				});
		// show dialog
		datePickerDialog.show();
	}
	
	/**
	 * Check field.
	 *
	 * @return the string
	 */
	private String checkField(){
		StringBuilder err_str = new StringBuilder();
		
		if(!Util.isInteger(txt_radius.getText().toString()))
			err_str.append(String.format(getResources()
					.getString(R.string.error_message_validation_radius)));
		
		if(!Util.checkDate(date_from, date_to))
			err_str.append(String.format(getResources()
					.getString(R.string.error_message_validation_date)));
			
		return err_str.toString();
	}
	
	
	/* (non-Javadoc)
	 * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
	 */
	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
		if(DIALOG_SHOW == SHOW_MAP_TYPE) {
			mGoogleMap.setMapType(mapType[position]);
		} else {
			
		}
	}

	/* (non-Javadoc)
	 * @see com.google.android.gms.maps.GoogleMap.OnMarkerClickListener#onMarkerClick(com.google.android.gms.maps.model.Marker)
	 */
	@Override
	public boolean onMarkerClick(Marker marker) {
		tappedMarker = marker;
		return true;
	}

	@Override
	public void onCameraChange(CameraPosition position) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	protected void onDestroy() {
		// clear all background to decrease memory
		mGoogleMap.clear();
		if(layout_header.getBackground() != null)
			layout_header.getBackground().setCallback(null);
		
		btn_back.setImageBitmap(null);
		btn_add_travel.setImageBitmap(null);
		btn_show_type.setImageBitmap(null);
		btn_show_photo.setImageBitmap(null);
		
	    DLog.e(TAG, "onDestroy A002");
	    DLog.e(TAG, "memory: " + Util.getMemory(this));
	    System.gc();
	    super.onDestroy();
	}
	
}
